home *** CD-ROM | disk | FTP | other *** search
/ The Utilities Experience / The Utilities Experience - Volume 1.iso / software / misc / o-z / x-windows / mesa-amiwin / src / pixel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-30  |  28.4 KB  |  1,233 lines

  1. /* pixel.c */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  1.2
  6.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25. $Id: pixel.c,v 1.12 1995/11/30 00:19:31 brianp Exp $
  26.  
  27. $Log: pixel.c,v $
  28.  * Revision 1.12  1995/11/30  00:19:31  brianp
  29.  * include stdio.h
  30.  *
  31.  * Revision 1.11  1995/11/17  14:30:41  brianp
  32.  * in gl_write_zoomed_*() limit spans to MAX_WIDTH, removed mallocs/frees
  33.  *
  34.  * Revision 1.10  1995/10/16  15:26:34  brianp
  35.  * added gl_write_zoomed_stencil_span
  36.  *
  37.  * Revision 1.9  1995/10/14  16:28:56  brianp
  38.  * added glPixelZoom support
  39.  *
  40.  * Revision 1.8  1995/09/15  18:39:07  brianp
  41.  * added update_drawpixels_state()
  42.  *
  43.  * Revision 1.7  1995/08/01  20:53:50  brianp
  44.  * added gl_save_pixelzoom()
  45.  *
  46.  * Revision 1.6  1995/07/24  20:35:20  brianp
  47.  * replaced memset() with MEMSET() and memcpy() with MEMCPY()
  48.  *
  49.  * Revision 1.5  1995/05/29  21:22:42  brianp
  50.  * added glGetPixelMap*() functions
  51.  *
  52.  * Revision 1.4  1995/05/22  21:02:41  brianp
  53.  * Release 1.2
  54.  *
  55.  * Revision 1.3  1995/05/12  16:57:22  brianp
  56.  * replaced CC.Mode!=0 with INSIDE_BEGIN_END
  57.  *
  58.  * Revision 1.2  1995/03/04  19:29:44  brianp
  59.  * 1.1 beta revision
  60.  *
  61.  * Revision 1.1  1995/02/24  14:25:08  brianp
  62.  * Initial revision
  63.  *
  64.  */
  65.  
  66.  
  67. /*
  68.  * glPixelStore, glPixelTransfer, glPixelMap, glPixelZoom, etc.
  69.  */
  70.  
  71.  
  72.  
  73. #include <assert.h>
  74. #include <stdio.h>
  75. #include <stdlib.h>
  76. #include <string.h>
  77. #include "context.h"
  78. #include "list.h"
  79. #include "macros.h"
  80. #include "pixel.h"
  81. #include "span.h"
  82. #include "stencil.h"
  83.  
  84.  
  85.  
  86. /*
  87.  * Flip the 8 bits in each byte of the given array.
  88.  */
  89. void gl_flip_bytes( GLubyte *p, GLuint n )
  90. {
  91.    register GLuint i, a, b;
  92.  
  93.    for (i=0;i<n;i++) {
  94.       b = (GLuint) p[i];
  95.       a = ((b & 0x01) << 7) |
  96.       ((b & 0x02) << 5) |
  97.       ((b & 0x04) << 3) |
  98.       ((b & 0x08) << 1) |
  99.       ((b & 0x10) >> 1) |
  100.       ((b & 0x20) >> 3) |
  101.       ((b & 0x40) >> 5) |
  102.       ((b & 0x80) >> 7);
  103.       p[i] = (GLubyte) a;
  104.    }
  105. }
  106.  
  107.  
  108. /*
  109.  * Flip the order of the 4 bytes in each word in the given array.
  110.  */
  111. static void swap4( GLuint *p, GLuint n )
  112. {
  113.    register GLuint i, a, b;
  114.  
  115.    for (i=0;i<n;i++) {
  116.       b = p[i];
  117.       a =  (b >> 24)
  118.     | ((b >> 8) & 0xff00)
  119.     | ((b << 8) & 0xff0000)
  120.     | ((b << 24) & 0xff000000);
  121.       p[i] = a;
  122.    }
  123. }
  124.  
  125.  
  126. /*
  127.  * Flip the order of the 2 bytes in each word in the given array.
  128.  */
  129. static void swap2( GLushort *p, GLuint n )
  130. {
  131.    register GLuint i;
  132.  
  133.    for (i=0;i<n;i++) {
  134.       p[i] = (p[i] >> 8) | ((p[i] << 8) & 0xff00);
  135.    }
  136. }
  137.  
  138.  
  139.  
  140.  
  141. /*
  142.  * Determine if we can use the optimized glDrawPixels function.
  143.  */
  144. static void update_drawpixels_state( void )
  145. {
  146.    if (CC.RGBAflag==GL_TRUE &&
  147.        CC.Pixel.RedBias==0.0   && CC.Pixel.RedScale==1.0 &&
  148.        CC.Pixel.GreenBias==0.0 && CC.Pixel.GreenScale==1.0 &&
  149.        CC.Pixel.BlueBias==0.0  && CC.Pixel.BlueScale==1.0 &&
  150.        CC.Pixel.AlphaBias==0.0 && CC.Pixel.AlphaScale==1.0 &&
  151.        CC.Pixel.MapColorFlag==GL_FALSE &&
  152.        CC.Pixel.ZoomX==1.0 && CC.Pixel.ZoomY==1.0 &&
  153.        CC.UnpackAlignment==4 &&
  154.        CC.UnpackRowLength==0 &&
  155.        CC.UnpackSkipPixels==0 &&
  156.        CC.UnpackSkipRows==0 &&
  157.        CC.UnpackSwapBytes==0 &&
  158.        CC.UnpackLSBFirst==0) {
  159.       CC.FastDrawPixels = GL_TRUE;
  160.    }
  161.    else {
  162.       CC.FastDrawPixels = GL_FALSE;
  163.    }
  164. }
  165.  
  166.  
  167.  
  168.  
  169. /**********************************************************************/
  170. /*****                    glPixelZoom                             *****/
  171. /**********************************************************************/
  172.  
  173.  
  174. /*
  175.  * Write a span of pixels to the frame buffer while applying a pixel zoom.
  176.  * This is only used by glDrawPixels and glCopyPixels.
  177.  * Input:  n - number of pixels in input row
  178.  *         x, y - destination of the span
  179.  *         z - depth values for the span
  180.  *         red, green, blue, alpha - array of colors
  181.  *         y0 - location of first row in the image we're drawing.
  182.  */
  183. void
  184. gl_write_zoomed_color_span( GLuint n, GLint x, GLint y, const GLint z[],
  185.                             const GLubyte red[], const GLubyte green[],
  186.                             const GLubyte blue[], const GLubyte alpha[],
  187.                             GLint y0 )
  188. {
  189.    GLint m;
  190.    GLint r0, r1, row, r;
  191.    GLint i, j, skipcol;
  192.    GLubyte zred[MAX_WIDTH], zgreen[MAX_WIDTH];  /* zoomed pixel colors */
  193.    GLubyte zblue[MAX_WIDTH], zalpha[MAX_WIDTH];
  194.    GLint zdepth[MAX_WIDTH];  /* zoomed depth values */
  195.  
  196.    /* compute width of output row */
  197.    m = (GLint) ABS( n * CC.Pixel.ZoomX );
  198.    if (m==0) {
  199.       return;
  200.    }
  201.    if (CC.Pixel.ZoomX<0.0) {
  202.       /* adjust x coordinate for left/right mirroring */
  203.       x = x - m;
  204.    }
  205.  
  206.    /* compute which rows to draw */
  207.    row = y-y0;
  208.    r0 = y0 + (GLint) (row * CC.Pixel.ZoomY);
  209.    r1 = y0 + (GLint) ((row+1) * CC.Pixel.ZoomY);
  210.    if (r0==r1) {
  211.       return;
  212.    }
  213.    else if (r1<r0) {
  214.       GLint rtmp = r1;
  215.       r1 = r0;
  216.       r0 = rtmp;
  217.    }
  218.  
  219.    /* make sure span isn't too long */
  220.    skipcol = 0;
  221.    if (m>MAX_WIDTH) {
  222.       /* shorten the span */
  223.       if (x<0) {
  224.          skipcol = -x;
  225.          m += x;
  226.       }
  227.       if (m>MAX_WIDTH) {
  228.          m = MAX_WIDTH - skipcol;
  229.       }
  230.       if (m<=0) {
  231.          return;
  232.       }
  233.    }
  234.  
  235.    assert( m <= MAX_WIDTH );
  236.  
  237.    /* zoom the span horizontally */
  238.    if (CC.Pixel.ZoomX==-1.0F) {
  239.       /* n==m */
  240.       for (j=0;j<m;j++) {
  241.          i = n - (j+skipcol) - 1;
  242.          zred[j]   = red[i];
  243.          zgreen[j] = green[i];
  244.          zblue[j]  = blue[i];
  245.          zalpha[j] = alpha[i];
  246.          zdepth[j] = z[i];
  247.       }
  248.    }
  249.    else {
  250.       GLfloat xscale = 1.0F / CC.Pixel.ZoomX;
  251.       for (j=0;j<m;j++) {
  252.          i = (j+skipcol) * xscale;
  253.          if (i<0)  i = n + i - 1;
  254.          zred[j]   = red[i];
  255.          zgreen[j] = green[i];
  256.          zblue[j]  = blue[i];
  257.          zalpha[j] = alpha[i];
  258.          zdepth[j] = z[i];
  259.       }
  260.    }
  261.  
  262.    /* write the span */
  263.    for (r=r0; r<r1; r++) {
  264.       gl_write_color_span( m, x+skipcol, r, zdepth,
  265.                            zred, zgreen, zblue, zalpha, GL_BITMAP );
  266.    }
  267. }
  268.  
  269.  
  270.  
  271. /*
  272.  * As above, but write CI pixels.
  273.  */
  274. void
  275. gl_write_zoomed_index_span( GLuint n, GLint x, GLint y, const GLint z[],
  276.                             const GLuint indexes[], GLint y0 )
  277. {
  278.    GLint m;
  279.    GLint r0, r1, row, r;
  280.    GLint i, j, skipcol;
  281.    GLuint zindexes[MAX_WIDTH];  /* zoomed color indexes */
  282.    GLint zdepth[MAX_WIDTH];  /* zoomed depth values */
  283.  
  284.    /* compute width of output row */
  285.    m = (GLint) ABS( n * CC.Pixel.ZoomX );
  286.    if (m==0) {
  287.       return;
  288.    }
  289.    if (CC.Pixel.ZoomX<0.0) {
  290.       /* adjust x coordinate for left/right mirroring */
  291.       x = x - m;
  292.    }
  293.  
  294.    /* compute which rows to draw */
  295.    row = y-y0;
  296.    r0 = y0 + (GLint) (row * CC.Pixel.ZoomY);
  297.    r1 = y0 + (GLint) ((row+1) * CC.Pixel.ZoomY);
  298.    if (r0==r1) {
  299.       return;
  300.    }
  301.    else if (r1<r0) {
  302.       GLint rtmp = r1;
  303.       r1 = r0;
  304.       r0 = rtmp;
  305.    }
  306.  
  307.    /* make sure span isn't too long */
  308.    skipcol = 0;
  309.    if (m>MAX_WIDTH) {
  310.       /* shorten the span */
  311.       if (x<0) {
  312.          skipcol = -x;
  313.          m += x;
  314.       }
  315.       if (m>MAX_WIDTH) {
  316.          m = MAX_WIDTH - skipcol;
  317.       }
  318.       if (m<=0) {
  319.          return;
  320.       }
  321.    }
  322.  
  323.    assert( m <= MAX_WIDTH );
  324.  
  325.    /* zoom the span horizontally */
  326.    if (CC.Pixel.ZoomX==-1.0F) {
  327.       /* n==m */
  328.       for (j=0;j<m;j++) {
  329.          i = n - (j+skipcol) - 1;
  330.          zindexes[j] = indexes[i];
  331.          zdepth[j]   = z[i];
  332.       }
  333.    }
  334.    else {
  335.       GLfloat xscale = 1.0F / CC.Pixel.ZoomX;
  336.       for (j=0;j<m;j++) {
  337.          i = (j+skipcol) * xscale;
  338.          if (i<0)  i = n + i - 1;
  339.          zindexes[j] = indexes[i];
  340.          zdepth[j] = z[i];
  341.       }
  342.    }
  343.  
  344.    /* write the span */
  345.    for (r=r0; r<r1; r++) {
  346.       gl_write_index_span( m, x+skipcol, r, zdepth, zindexes, GL_BITMAP );
  347.    }
  348. }
  349.  
  350.  
  351.  
  352. /*
  353.  * As above, but write stencil values.
  354.  */
  355. void
  356. gl_write_zoomed_stencil_span( GLuint n, GLint x, GLint y,
  357.                               const GLubyte stencil[], GLint y0 )
  358. {
  359.    GLint m;
  360.    GLint r0, r1, row, r;
  361.    GLint i, j, skipcol;
  362.    GLubyte zstencil[MAX_WIDTH];  /* zoomed stencil values */
  363.  
  364.    /* compute width of output row */
  365.    m = (GLint) ABS( n * CC.Pixel.ZoomX );
  366.    if (m==0) {
  367.       return;
  368.    }
  369.    if (CC.Pixel.ZoomX<0.0) {
  370.       /* adjust x coordinate for left/right mirroring */
  371.       x = x - m;
  372.    }
  373.  
  374.    /* compute which rows to draw */
  375.    row = y-y0;
  376.    r0 = y0 + (GLint) (row * CC.Pixel.ZoomY);
  377.    r1 = y0 + (GLint) ((row+1) * CC.Pixel.ZoomY);
  378.    if (r0==r1) {
  379.       return;
  380.    }
  381.    else if (r1<r0) {
  382.       GLint rtmp = r1;
  383.       r1 = r0;
  384.       r0 = rtmp;
  385.    }
  386.  
  387.    /* make sure span isn't too long */
  388.    skipcol = 0;
  389.    if (m>MAX_WIDTH) {
  390.       /* shorten the span */
  391.       if (x<0) {
  392.          skipcol = -x;
  393.          m += x;
  394.       }
  395.       if (m>MAX_WIDTH) {
  396.          m = MAX_WIDTH - skipcol;
  397.       }
  398.       if (m<=0) {
  399.          return;
  400.       }
  401.    }
  402.  
  403.    assert( m <= MAX_WIDTH );
  404.  
  405.    /* zoom the span horizontally */
  406.    if (CC.Pixel.ZoomX==-1.0F) {
  407.       /* n==m */
  408.       for (j=0;j<m;j++) {
  409.          i = n - (j+skipcol) - 1;
  410.          zstencil[j] = stencil[i];
  411.       }
  412.    }
  413.    else {
  414.       GLfloat xscale = 1.0F / CC.Pixel.ZoomX;
  415.       for (j=0;j<m;j++) {
  416.          i = (j+skipcol) * xscale;
  417.          if (i<0)  i = n + i - 1;
  418.          zstencil[j] = stencil[i];
  419.       }
  420.    }
  421.  
  422.    /* write the span */
  423.    for (r=r0; r<r1; r++) {
  424.       gl_write_stencil_span( m, x+skipcol, r, zstencil );
  425.    }
  426. }
  427.  
  428.  
  429.  
  430.  
  431. void glPixelZoom( GLfloat xfactor, GLfloat yfactor )
  432. {
  433.    if (CC.CompileFlag) {
  434.       gl_save_pixelzoom( xfactor, yfactor );
  435.    }
  436.    if (CC.ExecuteFlag) {
  437.       if (INSIDE_BEGIN_END) {
  438.      gl_error( GL_INVALID_OPERATION, "glPixelZoom" );
  439.      return;
  440.       }
  441.       CC.Pixel.ZoomX = xfactor;
  442.       CC.Pixel.ZoomY = yfactor;
  443.       update_drawpixels_state();
  444.    }
  445. }
  446.  
  447.  
  448.  
  449. /**********************************************************************/
  450. /*****                    glPixelStore                            *****/
  451. /**********************************************************************/
  452.  
  453.  
  454. void glPixelStorei( GLenum pname, GLint param )
  455. {
  456.    /* NOTE: this call can't be compiled into the display list */
  457.  
  458.    if (INSIDE_BEGIN_END) {
  459.       gl_error( GL_INVALID_OPERATION, "glPixelStore" );
  460.       return;
  461.    }
  462.  
  463.    switch (pname) {
  464.       case GL_PACK_SWAP_BYTES:
  465.          CC.PackSwapBytes = param ? GL_TRUE : GL_FALSE;
  466.      break;
  467.       case GL_PACK_LSB_FIRST:
  468.          CC.PackLSBFirst = param ? GL_TRUE : GL_FALSE;
  469.      break;
  470.       case GL_PACK_ROW_LENGTH:
  471.      if (param<0) {
  472.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  473.      }
  474.      else {
  475.         CC.PackRowLength = param;
  476.      }
  477.      break;
  478.       case GL_PACK_SKIP_PIXELS:
  479.      if (param<0) {
  480.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  481.      }
  482.      else {
  483.         CC.PackSkipPixels = param;
  484.      }
  485.      break;
  486.       case GL_PACK_SKIP_ROWS:
  487.      if (param<0) {
  488.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  489.      }
  490.      else {
  491.         CC.PackSkipRows = param;
  492.      }
  493.      break;
  494.       case GL_PACK_ALIGNMENT:
  495.          if (param==1 || param==2 || param==4 || param==8) {
  496.         CC.PackAlignment = param;
  497.      }
  498.      else {
  499.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  500.      }
  501.      break;
  502.       case GL_UNPACK_SWAP_BYTES:
  503.      CC.UnpackSwapBytes = param ? GL_TRUE : GL_FALSE;
  504.          break;
  505.       case GL_UNPACK_LSB_FIRST:
  506.      CC.UnpackLSBFirst = param ? GL_TRUE : GL_FALSE;
  507.      break;
  508.       case GL_UNPACK_ROW_LENGTH:
  509.      if (param<0) {
  510.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  511.      }
  512.      else {
  513.         CC.UnpackRowLength = param;
  514.      }
  515.      break;
  516.       case GL_UNPACK_SKIP_PIXELS:
  517.      if (param<0) {
  518.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  519.      }
  520.      else {
  521.         CC.UnpackSkipPixels = param;
  522.      }
  523.      break;
  524.       case GL_UNPACK_SKIP_ROWS:
  525.      if (param<0) {
  526.         gl_error( GL_INVALID_VALUE, "glPixelStore(param)" );
  527.      }
  528.      else {
  529.         CC.UnpackSkipRows = param;
  530.      }
  531.      break;
  532.       case GL_UNPACK_ALIGNMENT:
  533.          if (param==1 || param==2 || param==4 || param==8) {
  534.         CC.UnpackAlignment = param;
  535.      }
  536.      else {
  537.         gl_error( GL_INVALID_VALUE, "glPixelStore" );
  538.      }
  539.      break;
  540.       default:
  541.      gl_error( GL_INVALID_ENUM, "glPixelStore" );
  542.    }
  543.    update_drawpixels_state();
  544. }
  545.  
  546.  
  547.  
  548. void glPixelStoref( GLenum pname, GLfloat param )
  549. {
  550.    glPixelStorei( pname, (GLint) param );
  551. }
  552.  
  553.  
  554.  
  555. /**********************************************************************/
  556. /*****                         glPixelMap                         *****/
  557. /**********************************************************************/
  558.  
  559.  
  560.  
  561. void gl_pixel_map( GLenum map, GLint mapsize, const GLfloat *values )
  562. {
  563.    GLuint i;
  564.  
  565.    if (INSIDE_BEGIN_END) {
  566.       gl_error( GL_INVALID_OPERATION, "glPixelMapfv" );
  567.       return;
  568.    }
  569.  
  570.    if (mapsize<0 || mapsize>MAX_PIXEL_MAP_TABLE) {
  571.       gl_error( GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
  572.       return;
  573.    }
  574.  
  575.    if (map>=GL_PIXEL_MAP_S_TO_S && map<=GL_PIXEL_MAP_I_TO_A) {
  576.       /* test that mapsize is a power of two */
  577.       GLuint p;
  578.       GLboolean ok = GL_FALSE;
  579.       for (p=1; p<=MAX_PIXEL_MAP_TABLE; p=p<<1) {
  580.      if ( (p&mapsize) == p ) {
  581.         ok = GL_TRUE;
  582.         break;
  583.      }
  584.       }
  585.       if (!ok) {
  586.      gl_error( GL_INVALID_VALUE, "glPixelMapfv(mapsize)" );
  587.       }
  588.    }
  589.  
  590.    switch (map) {
  591.       case GL_PIXEL_MAP_S_TO_S:
  592.          for (i=0;i<mapsize;i++) {
  593.         CC.Pixel.MapStoS[i] = (GLint) values[i];
  594.      }
  595.      break;
  596.       case GL_PIXEL_MAP_I_TO_I:
  597.          for (i=0;i<mapsize;i++) {
  598.         CC.Pixel.MapItoI[i] = (GLint) values[i];
  599.      }
  600.      break;
  601.       case GL_PIXEL_MAP_I_TO_R:
  602.          for (i=0;i<mapsize;i++) {
  603.         CC.Pixel.MapItoR[i] = CLAMP( values[i], 0.0, 1.0 );
  604.      }
  605.      break;
  606.       case GL_PIXEL_MAP_I_TO_G:
  607.          for (i=0;i<mapsize;i++) {
  608.         CC.Pixel.MapItoG[i] = CLAMP( values[i], 0.0, 1.0 );
  609.      }
  610.      break;
  611.       case GL_PIXEL_MAP_I_TO_B:
  612.          for (i=0;i<mapsize;i++) {
  613.         CC.Pixel.MapItoB[i] = CLAMP( values[i], 0.0, 1.0 );
  614.      }
  615.      break;
  616.       case GL_PIXEL_MAP_I_TO_A:
  617.          for (i=0;i<mapsize;i++) {
  618.         CC.Pixel.MapItoA[i] = CLAMP( values[i], 0.0, 1.0 );
  619.      }
  620.      break;
  621.       case GL_PIXEL_MAP_R_TO_R:
  622.          for (i=0;i<mapsize;i++) {
  623.         CC.Pixel.MapRtoR[i] = CLAMP( values[i], 0.0, 1.0 );
  624.      }
  625.      break;
  626.       case GL_PIXEL_MAP_G_TO_G:
  627.          for (i=0;i<mapsize;i++) {
  628.         CC.Pixel.MapGtoG[i] = CLAMP( values[i], 0.0, 1.0 );
  629.      }
  630.      break;
  631.       case GL_PIXEL_MAP_B_TO_B:
  632.          for (i=0;i<mapsize;i++) {
  633.         CC.Pixel.MapBtoB[i] = CLAMP( values[i], 0.0, 1.0 );
  634.      }
  635.      break;
  636.       case GL_PIXEL_MAP_A_TO_A:
  637.          for (i=0;i<mapsize;i++) {
  638.         CC.Pixel.MapAtoA[i] = CLAMP( values[i], 0.0, 1.0 );
  639.      }
  640.      break;
  641.       default:
  642.          gl_error( GL_INVALID_ENUM, "glPixelMapfv(map)" );
  643.    }
  644. }
  645.  
  646.  
  647.  
  648. void glPixelMapfv( GLenum map, GLint mapsize, const GLfloat *values )
  649. {
  650.    if (CC.CompileFlag) {
  651.       gl_save_pixelmap( map, mapsize, values );
  652.    }
  653.    if (CC.ExecuteFlag) {
  654.       gl_pixel_map( map, mapsize, values );
  655.    }
  656. }
  657.  
  658.  
  659.  
  660.  
  661. void glPixelMapuiv( GLenum map, GLint mapsize, const GLuint *values )
  662. {
  663.    GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
  664.    GLuint i;
  665.  
  666.    if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) {
  667.       for (i=0;i<mapsize;i++) {
  668.      fvalues[i] = (GLfloat) values[i];
  669.       }
  670.    }
  671.    else {
  672.       for (i=0;i<mapsize;i++) {
  673.      fvalues[i] = UINT_TO_FLOAT( values[i] );
  674.       }
  675.    }
  676.    glPixelMapfv( map, mapsize, fvalues );
  677. }
  678.  
  679.  
  680.  
  681. void glPixelMapusv( GLenum map, GLint mapsize, const GLushort *values )
  682. {
  683.    GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
  684.    GLuint i;
  685.  
  686.    if (map==GL_PIXEL_MAP_I_TO_I || map==GL_PIXEL_MAP_S_TO_S) {
  687.       for (i=0;i<mapsize;i++) {
  688.      fvalues[i] = (GLfloat) values[i];
  689.       }
  690.    }
  691.    else {
  692.       for (i=0;i<mapsize;i++) {
  693.      fvalues[i] = USHORT_TO_FLOAT( values[i] );
  694.       }
  695.    }
  696.    glPixelMapfv( map, mapsize, fvalues );
  697. }
  698.  
  699.  
  700.  
  701. void glGetPixelMapfv( GLenum map, GLfloat *values )
  702. {
  703.    GLuint i;
  704.  
  705.    if (INSIDE_BEGIN_END) {
  706.       gl_error( GL_INVALID_OPERATION, "glGetPixelMapfv" );
  707.       return;
  708.    }
  709.    switch (map) {
  710.       case GL_PIXEL_MAP_I_TO_I:
  711.          for (i=0;i<CC.Pixel.MapItoIsize;i++) {
  712.         values[i] = (GLfloat) CC.Pixel.MapItoI[i];
  713.      }
  714.      break;
  715.       case GL_PIXEL_MAP_S_TO_S:
  716.          for (i=0;i<CC.Pixel.MapStoSsize;i++) {
  717.         values[i] = (GLfloat) CC.Pixel.MapStoS[i];
  718.      }
  719.      break;
  720.       case GL_PIXEL_MAP_I_TO_R:
  721.          MEMCPY(values,CC.Pixel.MapItoR,CC.Pixel.MapItoRsize*sizeof(GLfloat));
  722.      break;
  723.       case GL_PIXEL_MAP_I_TO_G:
  724.          MEMCPY(values,CC.Pixel.MapItoG,CC.Pixel.MapItoGsize*sizeof(GLfloat));
  725.      break;
  726.       case GL_PIXEL_MAP_I_TO_B:
  727.          MEMCPY(values,CC.Pixel.MapItoB,CC.Pixel.MapItoBsize*sizeof(GLfloat));
  728.      break;
  729.       case GL_PIXEL_MAP_I_TO_A:
  730.          MEMCPY(values,CC.Pixel.MapItoA,CC.Pixel.MapItoAsize*sizeof(GLfloat));
  731.      break;
  732.       case GL_PIXEL_MAP_R_TO_R:
  733.          MEMCPY(values,CC.Pixel.MapRtoR,CC.Pixel.MapRtoRsize*sizeof(GLfloat));
  734.      break;
  735.       case GL_PIXEL_MAP_G_TO_G:
  736.          MEMCPY(values,CC.Pixel.MapGtoG,CC.Pixel.MapGtoGsize*sizeof(GLfloat));
  737.      break;
  738.       case GL_PIXEL_MAP_B_TO_B:
  739.          MEMCPY(values,CC.Pixel.MapBtoB,CC.Pixel.MapBtoBsize*sizeof(GLfloat));
  740.      break;
  741.       case GL_PIXEL_MAP_A_TO_A:
  742.          MEMCPY(values,CC.Pixel.MapAtoA,CC.Pixel.MapAtoAsize*sizeof(GLfloat));
  743.      break;
  744.       default:
  745.          gl_error( GL_INVALID_ENUM, "glGetPixelMapfv" );
  746.    }
  747. }
  748.  
  749.  
  750. void glGetPixelMapuiv( GLenum map, GLuint *values )
  751. {
  752.    GLuint i;
  753.  
  754.    if (INSIDE_BEGIN_END) {
  755.       gl_error( GL_INVALID_OPERATION, "glGetPixelMapfv" );
  756.       return;
  757.    }
  758.    switch (map) {
  759.       case GL_PIXEL_MAP_I_TO_I:
  760.          MEMCPY(values, CC.Pixel.MapItoI, CC.Pixel.MapItoIsize*sizeof(GLint));
  761.      break;
  762.       case GL_PIXEL_MAP_S_TO_S:
  763.          MEMCPY(values, CC.Pixel.MapStoS, CC.Pixel.MapStoSsize*sizeof(GLint));
  764.      break;
  765.       case GL_PIXEL_MAP_I_TO_R:
  766.      for (i=0;i<CC.Pixel.MapItoRsize;i++) {
  767.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapItoR[i] );
  768.      }
  769.      break;
  770.       case GL_PIXEL_MAP_I_TO_G:
  771.      for (i=0;i<CC.Pixel.MapItoGsize;i++) {
  772.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapItoG[i] );
  773.      }
  774.      break;
  775.       case GL_PIXEL_MAP_I_TO_B:
  776.      for (i=0;i<CC.Pixel.MapItoBsize;i++) {
  777.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapItoB[i] );
  778.      }
  779.      break;
  780.       case GL_PIXEL_MAP_I_TO_A:
  781.      for (i=0;i<CC.Pixel.MapItoAsize;i++) {
  782.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapItoA[i] );
  783.      }
  784.      break;
  785.       case GL_PIXEL_MAP_R_TO_R:
  786.      for (i=0;i<CC.Pixel.MapRtoRsize;i++) {
  787.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapRtoR[i] );
  788.      }
  789.      break;
  790.       case GL_PIXEL_MAP_G_TO_G:
  791.      for (i=0;i<CC.Pixel.MapGtoGsize;i++) {
  792.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapGtoG[i] );
  793.      }
  794.      break;
  795.       case GL_PIXEL_MAP_B_TO_B:
  796.      for (i=0;i<CC.Pixel.MapBtoBsize;i++) {
  797.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapBtoB[i] );
  798.      }
  799.      break;
  800.       case GL_PIXEL_MAP_A_TO_A:
  801.      for (i=0;i<CC.Pixel.MapAtoAsize;i++) {
  802.         values[i] = FLOAT_TO_UINT( CC.Pixel.MapAtoA[i] );
  803.      }
  804.      break;
  805.       default:
  806.          gl_error( GL_INVALID_ENUM, "glGetPixelMapfv" );
  807.    }
  808. }
  809.  
  810.  
  811. void glGetPixelMapusv( GLenum map, GLushort *values )
  812. {
  813.    GLuint i;
  814.  
  815.    if (INSIDE_BEGIN_END) {
  816.       gl_error( GL_INVALID_OPERATION, "glGetPixelMapfv" );
  817.       return;
  818.    }
  819.    switch (map) {
  820.       case GL_PIXEL_MAP_I_TO_I:
  821.      for (i=0;i<CC.Pixel.MapItoIsize;i++) {
  822.         values[i] = (GLushort) CC.Pixel.MapItoI[i];
  823.      }
  824.      break;
  825.       case GL_PIXEL_MAP_S_TO_S:
  826.      for (i=0;i<CC.Pixel.MapStoSsize;i++) {
  827.         values[i] = (GLushort) CC.Pixel.MapStoS[i];
  828.      }
  829.      break;
  830.       case GL_PIXEL_MAP_I_TO_R:
  831.      for (i=0;i<CC.Pixel.MapItoRsize;i++) {
  832.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapItoR[i] );
  833.      }
  834.      break;
  835.       case GL_PIXEL_MAP_I_TO_G:
  836.      for (i=0;i<CC.Pixel.MapItoGsize;i++) {
  837.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapItoG[i] );
  838.      }
  839.      break;
  840.       case GL_PIXEL_MAP_I_TO_B:
  841.      for (i=0;i<CC.Pixel.MapItoBsize;i++) {
  842.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapItoB[i] );
  843.      }
  844.      break;
  845.       case GL_PIXEL_MAP_I_TO_A:
  846.      for (i=0;i<CC.Pixel.MapItoAsize;i++) {
  847.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapItoA[i] );
  848.      }
  849.      break;
  850.       case GL_PIXEL_MAP_R_TO_R:
  851.      for (i=0;i<CC.Pixel.MapRtoRsize;i++) {
  852.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapRtoR[i] );
  853.      }
  854.      break;
  855.       case GL_PIXEL_MAP_G_TO_G:
  856.      for (i=0;i<CC.Pixel.MapGtoGsize;i++) {
  857.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapGtoG[i] );
  858.      }
  859.      break;
  860.       case GL_PIXEL_MAP_B_TO_B:
  861.      for (i=0;i<CC.Pixel.MapBtoBsize;i++) {
  862.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapBtoB[i] );
  863.      }
  864.      break;
  865.       case GL_PIXEL_MAP_A_TO_A:
  866.      for (i=0;i<CC.Pixel.MapAtoAsize;i++) {
  867.         values[i] = FLOAT_TO_USHORT( CC.Pixel.MapAtoA[i] );
  868.      }
  869.      break;
  870.       default:
  871.          gl_error( GL_INVALID_ENUM, "glGetPixelMapfv" );
  872.    }
  873. }
  874.  
  875.  
  876.  
  877. /**********************************************************************/
  878. /*****                       glPixelTransfer                      *****/
  879. /**********************************************************************/
  880.  
  881.  
  882. void glPixelTransferf( GLenum pname, GLfloat param )
  883. {
  884.    if (INSIDE_BEGIN_END) {
  885.       gl_error( GL_INVALID_OPERATION, "glPixelTransfer" );
  886.       return;
  887.    }
  888.  
  889.    switch (pname) {
  890.        case GL_MAP_COLOR:
  891.          if (CC.CompileFlag) {
  892.         gl_save_set_boolean( &CC.Pixel.MapColorFlag,
  893.                  param ? GL_TRUE : GL_FALSE );
  894.      }
  895.          if (CC.ExecuteFlag) {
  896.         CC.Pixel.MapColorFlag = param ? GL_TRUE : GL_FALSE;
  897.      }
  898.      break;
  899.       case GL_MAP_STENCIL:
  900.          if (CC.CompileFlag) {
  901.         gl_save_set_boolean( &CC.Pixel.MapStencilFlag,
  902.                  param ? GL_TRUE : GL_FALSE );
  903.      }
  904.          if (CC.ExecuteFlag) {
  905.         CC.Pixel.MapStencilFlag = param ? GL_TRUE : GL_FALSE;
  906.      }
  907.      break;
  908.       case GL_INDEX_SHIFT:
  909.          if (CC.CompileFlag) {
  910.         gl_save_set_int( &CC.Pixel.IndexShift, (GLint) param );
  911.      }
  912.          if (CC.ExecuteFlag) {
  913.         CC.Pixel.IndexShift = (GLint) param;
  914.      }
  915.      break;
  916.       case GL_INDEX_OFFSET:
  917.          if (CC.CompileFlag) {
  918.         gl_save_set_int( &CC.Pixel.IndexOffset, (GLint) param );
  919.      }
  920.          if (CC.ExecuteFlag) {
  921.         CC.Pixel.IndexOffset = (GLint) param;
  922.      }
  923.      break;
  924.       case GL_RED_SCALE:
  925.          if (CC.CompileFlag) {
  926.         gl_save_set_float( &CC.Pixel.RedScale, param );
  927.      }
  928.          if (CC.ExecuteFlag) {
  929.         CC.Pixel.RedScale = param;
  930.      }
  931.      break;
  932.       case GL_RED_BIAS:
  933.          if (CC.CompileFlag) {
  934.         gl_save_set_float( &CC.Pixel.RedBias, param );
  935.      }
  936.          if (CC.ExecuteFlag) {
  937.         CC.Pixel.RedBias = param;
  938.      }
  939.      break;
  940.       case GL_GREEN_SCALE:
  941.          if (CC.CompileFlag) {
  942.         gl_save_set_float( &CC.Pixel.GreenScale, param );
  943.      }
  944.          if (CC.ExecuteFlag) {
  945.         CC.Pixel.GreenScale = param;
  946.      }
  947.      break;
  948.       case GL_GREEN_BIAS:
  949.          if (CC.CompileFlag) {
  950.         gl_save_set_float( &CC.Pixel.GreenBias, param );
  951.      }
  952.          if (CC.ExecuteFlag) {
  953.         CC.Pixel.GreenBias = param;
  954.      }
  955.      break;
  956.       case GL_BLUE_SCALE:
  957.          if (CC.CompileFlag) {
  958.         gl_save_set_float( &CC.Pixel.BlueScale, param );
  959.      }
  960.          if (CC.ExecuteFlag) {
  961.         CC.Pixel.BlueScale = param;
  962.      }
  963.      break;
  964.       case GL_BLUE_BIAS:
  965.          if (CC.CompileFlag) {
  966.         gl_save_set_float( &CC.Pixel.BlueBias, param );
  967.      }
  968.          if (CC.ExecuteFlag) {
  969.         CC.Pixel.BlueBias = param;
  970.      }
  971.      break;
  972.       case GL_ALPHA_SCALE:
  973.          if (CC.CompileFlag) {
  974.         gl_save_set_float( &CC.Pixel.AlphaScale, param );
  975.      }
  976.          if (CC.ExecuteFlag) {
  977.         CC.Pixel.AlphaScale = param;
  978.      }
  979.      break;
  980.       case GL_ALPHA_BIAS:
  981.          if (CC.CompileFlag) {
  982.         gl_save_set_float( &CC.Pixel.AlphaBias, param );
  983.      }
  984.          if (CC.ExecuteFlag) {
  985.         CC.Pixel.AlphaBias = param;
  986.      }
  987.      break;
  988.       case GL_DEPTH_SCALE:
  989.          if (CC.CompileFlag) {
  990.         gl_save_set_float( &CC.Pixel.DepthScale, param );
  991.      }
  992.          if (CC.ExecuteFlag) {
  993.         CC.Pixel.DepthScale = param;
  994.      }
  995.      break;
  996.       case GL_DEPTH_BIAS:
  997.          if (CC.CompileFlag) {
  998.         gl_save_set_float( &CC.Pixel.DepthBias, param );
  999.      }
  1000.          if (CC.ExecuteFlag) {
  1001.         CC.Pixel.DepthBias = param;
  1002.      }
  1003.      break;
  1004.       default:
  1005.          gl_error( GL_INVALID_ENUM, "glPixelTransfer(pname)" );
  1006.    }
  1007.    update_drawpixels_state();
  1008. }
  1009.  
  1010.  
  1011.  
  1012. void glPixelTransferi( GLenum pname, GLint param )
  1013. {
  1014.    glPixelTransferf( pname, (GLfloat) param );
  1015. }
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024. /*
  1025.  * Unpack pixel data according to parameters set by glPixelStore.
  1026.     GLint PackAlignment;
  1027.     GLint PackRowLength;
  1028.     GLint PackSkipPixels;
  1029.     GLint PackSkipRows;
  1030.     GLboolean PackSwapBytes;
  1031.     GLboolean PackLSBFirst;
  1032.  
  1033.     GLint UnpackAlignment;
  1034.     GLint UnpackRowLength;
  1035.     GLint UnpackSkipPixels;
  1036.     GLint UnpackSkipRows;
  1037.     GLboolean UnpackSwapBytes;
  1038.     GLboolean UnpackLSBFirst;
  1039.  */
  1040.  
  1041.  
  1042.  
  1043. /*
  1044.  * Compute ceiling of integer quotient of A divided by B:
  1045.  */
  1046. #define CEILING( A, B )  ( (A) % (B) == 0 ? (A)/(B) : (A)/(B)+1 )
  1047.  
  1048.  
  1049.  
  1050.  
  1051. /*
  1052.  * Unpack the given 2-D pixel array data.  The unpacked format will be con-
  1053.  * tiguous (no "empty" bytes) with byte/bit swapping applied as needed.
  1054.  * Input:  same as glDrawPixels
  1055.  * Output:  pointer to block of pixel data in same format and type as input
  1056.  *          or NULL if error.
  1057.  */
  1058. GLvoid *gl_unpack( GLsizei width, GLsizei height, GLenum format, GLenum type,
  1059.                const GLvoid *pixels )
  1060. {
  1061.    GLuint i, s, a, n, l, k;
  1062.    GLuint bytes, width_in_bytes;
  1063.    GLubyte *dst, *src, *buffer;
  1064.  
  1065.    /* Compute bytes per component */
  1066.    switch (type) {
  1067.       case GL_UNSIGNED_BYTE:
  1068.          s = sizeof(GLubyte);
  1069.      break;
  1070.       case GL_BYTE:
  1071.      s = sizeof(GLbyte);
  1072.      break;
  1073.       case GL_BITMAP:
  1074.      s = 0;  /* special case */
  1075.      break;
  1076.       case GL_UNSIGNED_SHORT:
  1077.      s = sizeof(GLushort);
  1078.      break;
  1079.       case GL_SHORT:
  1080.      s = sizeof(GLshort);
  1081.      break;
  1082.       case GL_UNSIGNED_INT:
  1083.      s = sizeof(GLuint);
  1084.      break;
  1085.       case GL_INT:
  1086.      s = sizeof(GLint);
  1087.      break;
  1088.       case GL_FLOAT:
  1089.      s = sizeof(GLfloat);
  1090.      break;
  1091.       default:
  1092.      gl_error( GL_INVALID_ENUM, "internal error in gl_unpack(type)" );
  1093.      return NULL;
  1094.    }
  1095.  
  1096.    /* Check if unpacking really is needed */
  1097. #ifdef LEAVEOUT
  1098.    if (!CC.UnpackSwapBytes && !CC.UnpackLSBFirst
  1099.        && CC.UnpackRowLength==0 && CC.UnpackSkipPixels==0
  1100.        && CC.UnpackSkipRows==0 && s>=CC.UnpackAlignment) {
  1101.       /* No unpacking has to be done */
  1102.       return (GLvoid *) pixels;
  1103.    }
  1104. #endif
  1105.  
  1106.    /* Compute number of components per pixel */
  1107.    switch (format) {
  1108.       case GL_COLOR_INDEX:
  1109.       case GL_STENCIL_INDEX:
  1110.       case GL_DEPTH_COMPONENT:
  1111.       case GL_RED:
  1112.       case GL_GREEN:
  1113.       case GL_BLUE:
  1114.       case GL_ALPHA:
  1115.       case GL_LUMINANCE:
  1116.          n = 1;
  1117.      break;
  1118.       case GL_LUMINANCE_ALPHA:
  1119.      n = 2;
  1120.      break;
  1121.       case GL_RGB:
  1122.      n = 3;
  1123.      break;
  1124.       case GL_RGBA:
  1125.      n = 4;
  1126.      break;
  1127.       default:
  1128.      gl_error( GL_INVALID_ENUM, "internal error in gl_unpack(format)" );
  1129.      return NULL;
  1130.    }
  1131.  
  1132.    /* Compute alignment and row length */
  1133.    a = CC.UnpackAlignment;
  1134.    if (CC.UnpackRowLength>0) {
  1135.       l = CC.UnpackRowLength;
  1136.    }
  1137.    else {
  1138.       l = width;
  1139.    }
  1140.  
  1141.    /*
  1142.     * Unpack!
  1143.     */
  1144.    if (type==GL_BITMAP) {
  1145.       /* BITMAP data */
  1146.  
  1147.       k = 8 * a * CEILING( n*l, 8*a );
  1148.  
  1149.       /* allocate storage for unpacked pixel data */
  1150.       bytes = CEILING( width * height , 8 );
  1151.       buffer = (GLubyte *) malloc( bytes );
  1152.       if (!buffer) {
  1153.      return NULL;
  1154.       }
  1155.  
  1156.       /* Copy/unpack pixel data to buffer */
  1157.       width_in_bytes = CEILING( width, 8 );
  1158.       src = (GLubyte *) pixels
  1159.         + CC.UnpackSkipRows * k
  1160.             + CC.UnpackSkipPixels / 8;
  1161.       dst = buffer;
  1162.       for (i=0;i<height;i++) {
  1163.      MEMCPY( dst, src, width_in_bytes );
  1164.      dst += width_in_bytes;
  1165.      src += k * s;
  1166.       }
  1167.       if (CC.UnpackLSBFirst) {
  1168.      /* reverse order of 8 bits in each byte */
  1169.      gl_flip_bytes( buffer, bytes );
  1170.       }
  1171.    }
  1172.    else {
  1173.       /* Non-BITMAP data */
  1174.  
  1175.       if (s>=a) {
  1176.      k = n * l;
  1177.       }
  1178.       else {
  1179.      k = a/s * CEILING( s*n*l, a );
  1180.       }
  1181.  
  1182.       /* allocate storage for unpacked pixel data */
  1183.       bytes = width * height * n * s;
  1184.       buffer = (GLubyte *) malloc( bytes );
  1185.       if (!buffer) {
  1186.      return NULL;
  1187.       }
  1188.  
  1189.       /* Copy/unpack pixel data to buffer */
  1190.       width_in_bytes = width * n * s;
  1191.       src = (GLubyte *) pixels
  1192.         + CC.UnpackSkipRows * k * s
  1193.             + CC.UnpackSkipPixels * n * s;
  1194.       dst = buffer;
  1195.       for (i=0;i<height;i++) {
  1196.      MEMCPY( dst, src, width_in_bytes );
  1197.      dst += width_in_bytes;
  1198.      src += k * s;
  1199.       }
  1200.  
  1201.       if (CC.UnpackSwapBytes && s>1) {
  1202.      if (s==2) {
  1203.         swap2( (GLushort *) buffer, bytes/2 );
  1204.      }
  1205.      else if (s==4) {
  1206.         swap4( (GLuint *) buffer, bytes/4 );
  1207.      }
  1208.       }
  1209.    }
  1210.  
  1211.    return (GLvoid *) buffer;
  1212. }
  1213.  
  1214.  
  1215.  
  1216.  
  1217. /*
  1218.    if (s>=a) {
  1219.       k = n * l;
  1220.    }
  1221.    else {  *s<a*
  1222.       k = (a/s) * ceil( s*n*l / a );
  1223.    }
  1224.  
  1225.    s = size in bytes of a single component
  1226.    a = alignment
  1227.    n = number of components in a pixel
  1228.    l = number of pixels in a row
  1229.  
  1230.    k = number of components or indices between first pixel in each row in mem.
  1231. */
  1232.  
  1233.